# encoding: utf-8
module ExpressionProcessor

	#
	#
	class ExpressionEvaluator
		attr_reader :exp, :data
		
		def initialize(data)
			@exp = /^(\w+[.\w]+)\s(eq|ne|gt|lt|gte|lte)\s(\w)$/
			@data = data
		end
		
		#
		#
		def evaluate(model, string)
			data ||= @exp.match(string)

			att_value = model.instance_eval(data[1])
			
			return false if att_value.nil?
			
			att_value	= att_value.to_s
			operator	= data[2]
			att_comp	= data[3]
			
			value = false
			
			case operator
				when "eq"
					value = (att_value == att_comp)
				when "ne"
					value = (att_value != att_comp)
				when "gt"
					value = (att_value > att_comp)
				when "lt"
					value = (att_value < att_comp)
				when "gte"
					value = (att_value >= att_comp)
				when "lte"
					value = (att_value <= att_comp)
			end
			
			return value
		end
	end
	
	#
	#
	class EmptyEvaluator < ExpressionEvaluator
		
		def initialize(data)
			@data = data
			@exp = /^(not empty|empty)\s+(\w+[.\w]+)/
		end
		
		#
		#
		def evaluate(model, string)
			data ||= @exp.match(string)

			operator	= data[1]
			att_value = model.instance_eval(data[2])
			
			return false if att_value.nil?

			value = false

			case operator
				when "empty"
					value = att_value.empty?
				when "not empty"
					value = att_value.any?
			end
			
			return value
		end
	end

	#
	#
	def evaluate_expression(model, string, var)
		value = nil
		
		if string.starts_with? var
			value = process_model(model, string.gsub("#{var}.", ""))
		end
		
		return value
	end
	
	private
	
	#
	#
	def evaluators
		[ExpressionEvaluator, EmptyEvaluator]
	end
	
	#
	#
	def get_evaluator(string)
		evaluators.each do |e|
			match = e.exp.match(string)
			unless match.nil?
				return e.new(match)
			end
		end
	end
end
